import logging
from typing import List

from fastapi import APIRouter, Depends, HTTPException, Body

from app.admin.schemas.role import Role, RoleCreate, RoleUpdate
from app.admin.schemas.user import User
from app.admin.services.role_service import role_service
from app.schemas.token import APIResponse
from app.security.auth import get_current_active_superuser, PermissionRequired

# 配置日志
logger = logging.getLogger(__name__)

router = APIRouter()


@router.post("", response_model=APIResponse[Role])
async def create_role(
        role: RoleCreate,
        tenant_id: str,
        current_user: User = Depends(get_current_active_superuser)
):
    """
    创建新角色（仅限超级用户）
    """
    logger.info(f"尝试创建角色: {role.name}, 租户ID: {tenant_id}")

    if await role_service.check_role_exists(role.name, tenant_id):
        logger.warning(f"角色创建失败: 角色名称 [{role.name}] 已存在")
        raise HTTPException(
            status_code=400,
            detail=APIResponse(code=400, msg=f"角色名称 [{role.name}] 已存在", data=None)
        )
    role.tenant_id = tenant_id
    created_role = await role_service.create_role(role=role)
    logger.info(f"角色创建成功: {created_role.id}, 名称: {created_role.name}")

    return APIResponse(
        code=200,
        msg="角色创建成功",
        data=created_role
    )


@router.get("", response_model=APIResponse[List[Role]])
async def read_roles(
        tenant_id: str,
        skip: int = 0,
        limit: int = 100,
        current_user: User = Depends(PermissionRequired("role_list"))
):
    """
    获取角色列表（需要角色访问权限）
    """
    logger.debug(f"获取角色列表, 租户ID: {tenant_id}, skip: {skip}, limit: {limit}")
    roles = await role_service.get_roles(skip=skip, limit=limit, tenant_id=tenant_id)
    return APIResponse(
        code=200,
        msg="获取角色列表成功",
        data=roles
    )


@router.get("/{role_id}", response_model=APIResponse[Role])
async def read_role(
        role_id: str,
        tenant_id: str,
        current_user: User = Depends(PermissionRequired("role_detail"))
):
    """
    根据ID获取角色信息（需要角色访问权限）
    """
    logger.debug(f"获取角色信息, 角色ID: {role_id}, 租户ID: {tenant_id}")
    db_role = await role_service.get_role(role_id=role_id, tenant_id=tenant_id)
    if db_role is None:
        logger.warning(f"获取角色失败: 角色 [{role_id}] 不存在")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"角色 [{role_id}] 不存在", data=None)
        )
    return APIResponse(
        code=200,
        msg="获取角色信息成功",
        data=db_role
    )


@router.put("/{role_id}", response_model=APIResponse[Role])
async def update_role(
        role_id: str,
        role_update: RoleUpdate,
        tenant_id: str,
        current_user: User = Depends(get_current_active_superuser)
):
    """
    更新角色信息（仅限超级用户）
    """
    logger.info(f"尝试更新角色: {role_id}, 租户ID: {tenant_id}")

    # 检查角色是否存在
    db_role = await role_service.get_role(role_id=role_id, tenant_id=tenant_id)
    if db_role is None:
        logger.warning(f"更新角色失败: 角色 [{role_id}] 不存在")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"角色 [{role_id}] 不存在", data=None)
        )

    # 设置租户ID
    role_update_dict = role_update.dict(exclude_unset=True)
    role_update_dict["tenant_id"] = tenant_id
    role_update = RoleUpdate(**role_update_dict)

    updated_role = await role_service.update_role(role_id=role_id, role_update=role_update)
    logger.info(f"角色更新成功: {role_id}")

    return APIResponse(
        code=200,
        msg="角色信息更新成功",
        data=updated_role
    )


@router.delete("/{role_id}", response_model=APIResponse[bool])
async def delete_role(
        role_id: str,
        tenant_id: str,
        current_user: User = Depends(get_current_active_superuser)
):
    """
    删除角色（仅限超级用户）
    """
    logger.info(f"尝试删除角色: {role_id}, 租户ID: {tenant_id}")

    # 检查角色是否存在
    db_role = await role_service.get_role(role_id=role_id, tenant_id=tenant_id)
    if db_role is None:
        logger.warning(f"删除角色失败: 角色 [{role_id}] 不存在")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"角色 [{role_id}] 不存在", data=None)
        )

    success = await role_service.delete_role(role_id=role_id, tenant_id=tenant_id)
    logger.info(f"角色删除成功: {role_id}")

    return APIResponse(
        code=200,
        msg="角色删除成功",
        data=success
    )


@router.get("/{role_id}/users", response_model=APIResponse[List[User]])
async def get_role_users(
        role_id: str,
        tenant_id: str,
        current_user: User = Depends(PermissionRequired("role_users"))
):
    """
    获取角色的用户列表（需要角色访问权限）
    """
    logger.debug(f"获取角色用户列表, 角色ID: {role_id}, 租户ID: {tenant_id}")

    # 检查角色是否存在
    db_role = await role_service.get_role(role_id=role_id, tenant_id=tenant_id)
    if db_role is None:
        logger.warning(f"获取角色用户列表失败: 角色 [{role_id}] 不存在")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"角色 [{role_id}] 不存在", data=None)
        )

    users = await role_service.get_role_users(role_id=role_id, tenant_id=tenant_id)
    return APIResponse(
        code=200,
        msg="获取角色用户列表成功",
        data=users
    )


@router.post("/{role_id}/resources", response_model=APIResponse[bool])
async def set_role_resources(
        role_id: str,
        tenant_id: str,
        resource_ids: List[str] = Body(..., embed=True),
        current_user: User = Depends(get_current_active_superuser)
):
    """
    角色增加资源权限（仅限超级用户）
    会覆盖当前角色所有资源
    """
    logger.info(f"尝试设置角色资源: 角色ID: {role_id}, 租户ID: {tenant_id}")

    # 检查角色是否存在
    db_role = await role_service.get_role(role_id=role_id, tenant_id=tenant_id)
    if db_role is None:
        logger.warning(f"设置角色资源失败: 角色 [{role_id}] 不存在")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg=f"角色 [{role_id}] 不存在", data=None)
        )

    success = await role_service.set_role_resource(role_id=role_id, resource_ids=resource_ids, tenant_id=tenant_id)
    if not success:
        logger.warning(f"设置角色资源失败: 资源不存在")
        raise HTTPException(
            status_code=404,
            detail=APIResponse(code=404, msg="资源不存在", data=None)
        )

    logger.info(f"角色资源设置成功: {role_id}")

    return APIResponse(
        code=200,
        msg="角色资源设置成功",
        data=True
    )
